GIC: Add API to get interrupt active status
authorJeenu Viswambharan <[email protected]>
Fri, 22 Sep 2017 07:32:09 +0000 (08:32 +0100)
committerJeenu Viswambharan <[email protected]>
Mon, 16 Oct 2017 15:50:01 +0000 (16:50 +0100)
API documentation updated.

Change-Id: I6d61785af0d5330930c709de971a904dc7c3516c
Co-authored-by: Yousuf A <[email protected]>
Signed-off-by: Jeenu Viswambharan <[email protected]>
12 files changed:
docs/platform-interrupt-controller-API.rst
drivers/arm/gic/common/gic_common.c
drivers/arm/gic/common/gic_common_private.h
drivers/arm/gic/v2/gicv2_main.c
drivers/arm/gic/v3/gicv3_helpers.c
drivers/arm/gic/v3/gicv3_main.c
drivers/arm/gic/v3/gicv3_private.h
include/drivers/arm/gicv2.h
include/drivers/arm/gicv3.h
include/plat/common/platform.h
plat/common/plat_gicv2.c
plat/common/plat_gicv3.c

index a94a90c755536e40c73b90e0067e25226b177e3b..d0a2ad27690892ed95ce97727428df4d9918a4c3 100644 (file)
@@ -66,6 +66,21 @@ as a Software Generated Interrupt. Software Generated Interrupts are raised by
 explicit programming by software, and are typically used in inter-PE
 communication. Secure SGIs are reserved for use by Secure world software.
 
+Function: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : unsigned int
+    Return   : int
+
+This API should return the *active* status of the interrupt ID specified by the
+first parameter, ``id``.
+
+In case of ARM standard platforms using GIC, the implementation of the API reads
+the GIC *Set Active Register* to read and return the active status of the
+interrupt.
+
 ----
 
 *Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*
index 6535813f9898d33f3f047ff17af4f8f57afd573e..71155a9708c5dbffc3c699c556ea050a210820a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -273,6 +273,14 @@ void gicd_set_icpendr(uintptr_t base, unsigned int id)
        gicd_write_icpendr(base, id, (1 << bit_num));
 }
 
+unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
+{
+       unsigned int bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
+       unsigned int reg_val = gicd_read_isactiver(base, id);
+
+       return (reg_val >> bit_num) & 0x1;
+}
+
 void gicd_set_isactiver(uintptr_t base, unsigned int id)
 {
        unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
index 2077cc464a97a1ae8686349ceb89910692c27524..8b96b37bb3d90a301e01c5ff843d5ee8cd095c31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,6 +73,7 @@ void gicd_set_isenabler(uintptr_t base, unsigned int id);
 void gicd_set_icenabler(uintptr_t base, unsigned int id);
 void gicd_set_ispendr(uintptr_t base, unsigned int id);
 void gicd_set_icpendr(uintptr_t base, unsigned int id);
+unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id);
 void gicd_set_isactiver(uintptr_t base, unsigned int id);
 void gicd_set_icactiver(uintptr_t base, unsigned int id);
 void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
index 28266807c25f1fd7d787c800c722eb2c6566cd6d..e33353a88346a07402f13f1ff50fec2f6c8858d1 100644 (file)
@@ -275,3 +275,16 @@ void gicv2_set_pe_target_mask(unsigned int proc_num)
        driver_data->target_masks[proc_num] =
                gicv2_get_cpuif_id(driver_data->gicd_base);
 }
+
+/*******************************************************************************
+ * This function returns the active status of the interrupt (either because the
+ * state is active, or active and pending).
+ ******************************************************************************/
+unsigned int gicv2_get_interrupt_active(unsigned int id)
+{
+       assert(driver_data);
+       assert(driver_data->gicd_base);
+       assert(id <= MAX_SPI_ID);
+
+       return gicd_get_isactiver(driver_data->gicd_base, id);
+}
index 73ad060f6dd0714379b642aa39c51c913c0ec2b0..81d50ad45f4b13c7a801ba2335e1141cc89a4f31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -171,6 +171,18 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id)
        gicr_write_isenabler0(base, (1 << bit_num));
 }
 
+/*
+ * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor
+ * ISACTIVER0.
+ */
+unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
+{
+       unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
+       unsigned int reg_val = gicr_read_isactiver0(base);
+
+       return (reg_val >> bit_num) & 0x1;
+}
+
 /*
  * Accessor to set the byte corresponding to interrupt ID
  * in GIC Re-distributor IPRIORITYR.
index 7e7574306706eef78e3f07b75bc78c4df72df1b5..08cf0957d08ec26f57ecf8de70390cd5e29a8924 100644 (file)
@@ -778,3 +778,30 @@ unsigned int gicv3_get_running_priority(void)
 {
        return read_icc_rpr_el1();
 }
+
+/*******************************************************************************
+ * This function checks if the interrupt identified by id is active (whether the
+ * state is either active, or active and pending). The proc_num is used if the
+ * interrupt is SGI or PPI and programs the corresponding Redistributor
+ * interface.
+ ******************************************************************************/
+unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
+{
+       unsigned int value;
+
+       assert(gicv3_driver_data);
+       assert(gicv3_driver_data->gicd_base);
+       assert(proc_num < gicv3_driver_data->rdistif_num);
+       assert(gicv3_driver_data->rdistif_base_addrs);
+       assert(id <= MAX_SPI_ID);
+
+       if (id < MIN_SPI_ID) {
+               /* For SGIs and PPIs */
+               value = gicr_get_isactiver0(
+                               gicv3_driver_data->rdistif_base_addrs[proc_num], id);
+       } else {
+               value = gicd_get_isactiver(gicv3_driver_data->gicd_base, id);
+       }
+
+       return value;
+}
index 59298edf2de1aa9e515b77794b4b6edd0a70950f..bb8ad9ae8303ded37836603a9c700f4520ad9dca 100644 (file)
@@ -67,6 +67,7 @@ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val);
 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id);
 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id);
 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id);
+unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id);
 void gicd_set_igrpmodr(uintptr_t base, unsigned int id);
 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id);
 void gicr_set_isenabler0(uintptr_t base, unsigned int id);
index c91cc1b049cc3b8293241892ca611b886734b4ca..2b461263759b48cce183b006c35de94c458c4b82 100644 (file)
@@ -147,6 +147,7 @@ void gicv2_end_of_interrupt(unsigned int id);
 unsigned int gicv2_get_interrupt_group(unsigned int id);
 unsigned int gicv2_get_running_priority(void);
 void gicv2_set_pe_target_mask(unsigned int proc_num);
+unsigned int gicv2_get_interrupt_active(unsigned int id);
 
 #endif /* __ASSEMBLY__ */
 #endif /* __GICV2_H__ */
index 4548a87c8bd3186ce7ed23c903182b2bae70c677..ec272ea7c0ba87fd2828de9e43b4925ed1d79dcd 100644 (file)
@@ -350,6 +350,7 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx
 void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx);
 
 unsigned int gicv3_get_running_priority(void);
+unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num);
 
 #endif /* __ASSEMBLY__ */
 #endif /* __GICV3_H__ */
index f00db0db2389fc4d41be22a8e2108075bc6531fa..e4fb6a9f939b45c30e58f4b581bd8ed1099b9ec4 100644 (file)
@@ -76,6 +76,7 @@ unsigned int plat_ic_get_running_priority(void);
 int plat_ic_is_spi(unsigned int id);
 int plat_ic_is_ppi(unsigned int id);
 int plat_ic_is_sgi(unsigned int id);
+unsigned int plat_ic_get_interrupt_active(unsigned int id);
 
 /*******************************************************************************
  * Optional common functions (may be overridden)
index 7d91f792291870dd76705e16ad76077a100fe2d9..5a92b66b942f127abd781c2c574516322b553b50 100644 (file)
@@ -24,6 +24,7 @@
 #pragma weak plat_ic_is_spi
 #pragma weak plat_ic_is_ppi
 #pragma weak plat_ic_is_sgi
+#pragma weak plat_ic_get_interrupt_active
 
 /*
  * This function returns the highest priority pending interrupt at
@@ -147,3 +148,8 @@ int plat_ic_is_sgi(unsigned int id)
 {
        return (id >= MIN_SGI_ID) && (id < MIN_PPI_ID);
 }
+
+unsigned int plat_ic_get_interrupt_active(unsigned int id)
+{
+       return gicv2_get_interrupt_active(id);
+}
index 5a6021c4afdcc40496eaad1a4fde1aea18cdcabd..abb3f1d16f2ef75149d83143831347f73b7ad3a7 100644 (file)
@@ -30,6 +30,7 @@
 #pragma weak plat_ic_is_spi
 #pragma weak plat_ic_is_ppi
 #pragma weak plat_ic_is_sgi
+#pragma weak plat_ic_get_interrupt_active
 
 CASSERT((INTR_TYPE_S_EL1 == INTR_GROUP1S) &&
        (INTR_TYPE_NS == INTR_GROUP1NS) &&
@@ -180,6 +181,11 @@ int plat_ic_is_sgi(unsigned int id)
 {
        return (id >= MIN_SGI_ID) && (id < MIN_PPI_ID);
 }
+
+unsigned int plat_ic_get_interrupt_active(unsigned int id)
+{
+       return gicv3_get_interrupt_active(id, plat_my_core_pos());
+}
 #endif
 #ifdef IMAGE_BL32